package com.quan.sdk.weixin.tools;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mzlion.easyokhttp.HttpClient;
import com.mzlion.easyokhttp.response.HttpResponse;
import com.quan.sdk.weixin.common.WeixinContext;
import com.quan.sdk.weixin.model.QrCode;
import com.quan.sdk.weixin.model.QrCodeTicket;

/**
 * 公众号二维码工具类
 * @author yhaoquan
 *
 */
public class QRCodeTools {

	private static Logger logger = LoggerFactory.getLogger(QRCodeTools.class);
	
	/**
	 * 创建二维码ticket
	 * <br>方式：POST
	 * <br>参数：
	 * <br>&nbsp;&nbsp;&nbsp; access_token 全局唯一接口调用凭据
	 */
	public static String QR_CODE_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s" ;
	
	/**
	 * 通过二维码的Ticket获取二维码图片的URL
	 * <br>参数：
	 * <br>&nbsp;&nbsp;&nbsp; ticket 二维码的Ticket
	 */
	public static String QR_CODE_SHOW_URL = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s" ;
	
	/**
	 * 生成临时二维码，默认过期时间（7天）
	 * @param accessToken 公众号的全局唯一接口调用凭据
	 * @param sceneValue 场景值
	 * @return
	 */
	public static String generateQRCodeTemp(Object sceneValue) {
		return generateQRCodeTemp(null, QrCodeTempType.QR_STR_SCENE, sceneValue, null) ;
	}
	/**
	 * 生成临时二维码
	 * @param accessToken 公众号的全局唯一接口调用凭据
	 * @param expire_seconds 过期时间（秒）
	 * @param sceneValue 场景值
	 * @return
	 */
	public static String generateQRCodeTemp(Object sceneValue, Long expire_seconds) {
		return generateQRCodeTemp(null, QrCodeTempType.QR_STR_SCENE, sceneValue, expire_seconds) ;
	}
	
	/**
	 * 生成临时二维码
	 * @param action_name 临时整形参数值：QR_SCENE, 临时字符参数值：QR_STR_SCENE
	 * @param sceneValue 场景值
	 * @param expire_seconds 过期时间（默认7天:604800）：秒
	 * @return
	 */
	public static String generateQRCodeTemp(QrCodeTempType action_name, Object sceneValue, Long expire_seconds) {
		return generateQRCodeTemp(null, action_name, sceneValue, expire_seconds) ;
	}
	
	/**
	 * 生成临时二维码
	 * @param accessToken 公众号的全局唯一接口调用凭据
	 * @param action_name 临时整形参数值：QR_SCENE, 临时字符参数值：QR_STR_SCENE
	 * @param sceneValue 场景值
	 * @param expire_seconds 过期时间（默认7天:604800）：秒
	 * @return 二维码图片的URL
	 */
	public static String generateQRCodeTemp(String accessToken, QrCodeTempType action_name, Object sceneValue, Long expire_seconds) {
		if(StringUtils.isEmpty(accessToken)) {
			accessToken = WeixinContext.getAccessToken() ;
		}
		if(StringUtils.isEmpty(accessToken)) {
			logger.info("生成临时二维码需要微信全局唯一凭证AccessToken");
			return null;
		}
		
		//获取创建二维码ticket
		String qrCodeTicket = null ;
		
		if(QrCodeTempType.QR_SCENE.equals(action_name)) {//整形参数
			if(null != sceneValue) {//带场景值
				try {
					qrCodeTicket = QrCodeTicket.sceneIntVal(expire_seconds, QrCodeTempType.QR_SCENE.name(), Integer.parseInt(sceneValue.toString()));
				} catch (NumberFormatException e) {
					return "场景值参数需为整形" ;
				}
			} else {
				qrCodeTicket = QrCodeTicket.sceneIntVal(expire_seconds, QrCodeTempType.QR_SCENE.name());
			}
			logger.debug("创建二维码ticket：{}", qrCodeTicket);
		} 
		
		if(QrCodeTempType.QR_STR_SCENE.equals(action_name)) {//字符参数
			if(null != sceneValue) {//带场景值
				qrCodeTicket = QrCodeTicket.sceneStrVal(expire_seconds, QrCodeTempType.QR_STR_SCENE.name(), sceneValue.toString());
			} else {
				qrCodeTicket = QrCodeTicket.sceneStrVal(expire_seconds, QrCodeTempType.QR_STR_SCENE.name());
			}
		}
		
		if(null != qrCodeTicket) {
			try {
				String url = String.format(QR_CODE_TICKET_URL, accessToken);
				HttpResponse response = HttpClient.textBody(url).json(qrCodeTicket).execute();
				QrCode qrCode = response.asBean(QrCode.class) ;
				logger.debug("获取二维码Ticket：{}", qrCode);
				if(null != qrCode) {
					//返回二维码图片的URL
					String qrCodeUrl = String.format(QR_CODE_SHOW_URL, URLEncoder.encode(qrCode.getTicket(), "UTF-8")) ;
					logger.debug("临时二维码图片URL：{}", qrCodeUrl);
					return qrCodeUrl ;
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	/**
	 * 生成永久二维码
	 * @param action_name 永久整形参数值：QR_LIMIT_SCENE, 永久字符参数值：QR_LIMIT_STR_SCENE
	 * @param sceneValue 场景值
	 * @return 二维码图片的URL
	 */
	public static String generateQRCodeForever(QrCodeForeverType action_name, Object sceneValue) {
		return generateQRCodeForever(null, action_name, sceneValue) ;
	}
	
	/**
	 * 生成永久二维码
	 * @param accessToken
	 * @param action_name 永久整形参数值：QR_LIMIT_SCENE, 永久字符参数值：QR_LIMIT_STR_SCENE
	 * @param sceneValue 场景值
	 * @return 二维码图片的URL
	 */
	public static String generateQRCodeForever(String accessToken, QrCodeForeverType action_name, Object sceneValue) {
		if(StringUtils.isEmpty(accessToken)) {
			accessToken = WeixinContext.getAccessToken() ;
		}
		if(StringUtils.isEmpty(accessToken)) {
			logger.info("生成临时二维码需要微信全局唯一凭证AccessToken");
			return null;
		}
		
		//获取创建二维码ticket
		String qrCodeTicket = null ;
		
		//整形参数
		if(QrCodeForeverType.QR_LIMIT_SCENE.equals(action_name.name())) {
			if(null != sceneValue) {//带场景值
				try {
					qrCodeTicket = QrCodeTicket.sceneIntVal(QrCodeForeverType.QR_LIMIT_SCENE.name(), Integer.parseInt(sceneValue.toString()));
				} catch (NumberFormatException e) {
					return "场景值参数需为整形" ;
				}
			} else {
				qrCodeTicket = QrCodeTicket.sceneIntVal(QrCodeForeverType.QR_LIMIT_SCENE.name());
			}
			logger.info("创建二维码ticket：{}", qrCodeTicket);
		}
		if(QrCodeForeverType.QR_LIMIT_STR_SCENE.equals(action_name.name())) {
			if(null != sceneValue) {//带场景值
				qrCodeTicket = QrCodeTicket.sceneStrVal(QrCodeForeverType.QR_LIMIT_STR_SCENE.name(), sceneValue.toString());
			} else {
				qrCodeTicket = QrCodeTicket.sceneStrVal(QrCodeForeverType.QR_LIMIT_STR_SCENE.name());
			}
		}
		if(null != qrCodeTicket) {
			try {
				String url = String.format(QR_CODE_TICKET_URL, accessToken);
				HttpResponse response = HttpClient.textBody(url).json(qrCodeTicket).execute();
				QrCode qrCode = response.asBean(QrCode.class) ;
				logger.debug("获取二维码Ticket：{}", qrCode);
				if(null != qrCode) {
					//返回二维码图片的URL
					String qrCodeUrl = String.format(QR_CODE_SHOW_URL, URLEncoder.encode(qrCode.getTicket(), "UTF-8")) ;
					logger.info("永久二维码图片URL：{}", qrCodeUrl);
					return qrCodeUrl ;
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	/**
	 * 临时二维码参数类型
	 * <br>QR_SCENE 数值型临时二维码
	 * <br>QR_STR_SCENE 字符串型临时二维码
	 * <br>QR_LIMIT_SCENE 数值型永久二维码
	 * <br>QR_LIMIT_STR_SCENE 字符串型永久二维码
	 */
	public enum QrCodeTempType {
		QR_SCENE, QR_STR_SCENE
	}
	
	/**
	 * 永久二维码参数类型
	 * <br>QR_LIMIT_SCENE 数值型永久二维码
	 * <br>QR_LIMIT_STR_SCENE 字符串型永久二维码
	 */
	public enum QrCodeForeverType {
		QR_LIMIT_SCENE, QR_LIMIT_STR_SCENE
	}
	
}
